package cn.com.chengmandian.bike.service.impl;

import cn.com.chengmandian.bike.mapper.EbDevicePathMapper;
import cn.com.chengmandian.bike.model.EbDevicePath;
import cn.com.chengmandian.bike.model.EbRideOrder;
import cn.com.chengmandian.bike.service.IEbDevicePathService;
import cn.com.chengmandian.bike.service.IEbRideOrderService;
import cn.com.chengmandian.core.common.utils.LnglatUtil;
import cn.com.chengmandian.core.redis.service.RedisService;
import cn.com.chengmandian.core.web.exceptions.BadResponseException;
import cn.com.chengmandian.core.web.pojo.AjaxResult;
import cn.com.chengmandian.service.bike.IotBikeClient;
import cn.com.chengmandian.service.bike.dto.BikeGpsDto;
import cn.com.chengmandian.service.bike.pojo.DevicePath;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 车辆轨迹坐标数据表 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-11
 */
@Slf4j
@Service
public class EbDevicePathServiceImpl extends ServiceImpl<EbDevicePathMapper, EbDevicePath> implements IEbDevicePathService {
    @Autowired
    private IEbRideOrderService rideOrderService;

    @Resource
    private IotBikeClient iotBikeClient;

    @Autowired
    private RedisService redisService;

    @Override
    public List<DevicePath> getOrderPaths(String orderNo, Integer memberId) {
        EbRideOrder rideOrder = rideOrderService.getByNo(orderNo, memberId);
        Assert.notNull(rideOrder, "订单不存在");
        return getOrderPaths(rideOrder.getBikeId(),rideOrder.getOpenTime(),rideOrder.getCloseTime(),null);
    }

    /**
     * 获取订单公里数
     */
    @Override
    public Integer getDistance(Integer bikeId, Date startTime, Date endTime, Boolean isClose) {
        try {
            String key = "CMD:BIKE:DISTANCE:" + bikeId + ":" + DateUtil.format(startTime, "yyyyMMddHHmmss");
            if (!isClose) {
                try {
                    Object res = redisService.get(key);
                    if (res != null) return Integer.parseInt(res.toString());
                } catch (Exception e) {
                    log.error("getDistance error!", e);
                }
            }
            List<DevicePath> list = getOrderPaths(bikeId,startTime,endTime, null);
            Double res = 0.0;
            if (list.size() > 1) {
                for(int i = 0; i < list.size() - 1; i ++) {
                    res = res  + LnglatUtil.getDistance(list.get(i).getLng().doubleValue(), list.get(i).getLat().doubleValue(), list.get(i + 1).getLng().doubleValue(), list.get(i + 1).getLat().doubleValue());
                }
            }
            // 支持最大公里数
            if (res > 200000) return 200000;
            if (!isClose) redisService.set(key, res.intValue(), 60);
            return res.intValue();
        } catch (Exception e) {
            log.error("getOrderInstance error!", e);
            return 0;
        }
    }

    private List<DevicePath> getOrderPaths(Integer bikeId,Date startTime, Date endTime ,Integer moveStatus) {
        //1.如果startTime 是24小时之内的 直接读db
//        if(DateUtil.between(startTime,new Date(), DateUnit.HOUR)<24){
//            return this.list(new LambdaQueryWrapper<EbDevicePath>()
//                    .eq(EbDevicePath::getBikeId, bikeId)
//                    .ge(EbDevicePath::getCreateTime, startTime)
//                    .le(endTime != null, EbDevicePath::getCreateTime, endTime)
//                    .eq(moveStatus!=null,EbDevicePath::getMoveStatus,moveStatus)
//                    .orderByAsc(EbDevicePath::getId));
//        }

        //2. 24小时之外 读微服务接口
        BikeGpsDto dto = new BikeGpsDto();
        dto.setBikeId(bikeId);
        dto.setStartTime(startTime);
        dto.setEndTime(endTime != null ? endTime : new Date());

        AjaxResult<List<DevicePath>> ajaxResult = iotBikeClient.bikePathLog(dto);
        if (ajaxResult.isSuccess()) {
            List<DevicePath> resultList = ajaxResult.getData();
            if(moveStatus==null){
                return resultList;
            }else{
                List<DevicePath> moveList = new ArrayList<>();
                resultList.forEach(m -> {
                    if (m.getMoveStatus().equals(1)) {
                        moveList.add(m);
                    }
                });
                return moveList;
            }
        } else {
            log.error("查询轨迹数据失败:" + ajaxResult.getMessage());
            throw new BadResponseException("轨迹加载失败 请稍后再试");
        }
    }
}
